package org.openmore.platform.controller;

import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import io.swagger.annotations.*;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import org.openmore.platform.dto.common.BaseResponse;
import org.openmore.platform.wechatMini.WechatMiniAppService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;

/**
 * 微信小程序用户接口
 *
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@Api(value = "/WechatMiniapp", tags = "WechatMiniapp", description = "小程序相关接口")
@RequestMapping(value = "/api/wechatMiniapp", produces = {APPLICATION_JSON_UTF8_VALUE})
@RestController
public class WxMiniAppController extends BaseController{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WechatMiniAppService wechatMiniAppService;
    /**
     * 登陆接口使用code换取openID等信息
     */
    @ApiOperation(value = "小程序登录接口", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = WxMaJscode2SessionResult.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/{tenantId}/login/{code}")
    public BaseResponse login(@PathVariable @ApiParam(name = "应用ID") String tenantId,
                              @PathVariable @ApiParam(name = "从小程序获取的code") String code) {
        return BaseResponse.buildSuccessResponse(wechatMiniAppService.login(tenantId, code));
    }

    /**
     * 获取用户信息接口
     */
    @ApiOperation(value = "小程序获取用户身份信息", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = WxMaUserInfo.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/{tenantId}/info")
    public BaseResponse info(@PathVariable @ApiParam("应用ID")String tenantId,
                             @RequestParam(required = true) @ApiParam("sessionKey")String sessionKey,
                             @RequestParam(required = true) @ApiParam("signature")String signature,
                             @RequestParam(required = true) @ApiParam("rawData")String rawData,
                             @RequestParam(required = true) @ApiParam("encryptedData")String encryptedData,
                             @RequestParam(required = true) @ApiParam("iv")String iv) {
        return BaseResponse.buildSuccessResponse(wechatMiniAppService.info(tenantId, sessionKey, signature, rawData, encryptedData, iv));
    }

    /**
     * 获取用户绑定手机号信息
     */
    @ApiOperation(value = "小程序获取用户绑定手机号信息", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = WxMaPhoneNumberInfo.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/{tenantId}/getPhone")
    public BaseResponse phone(@PathVariable @ApiParam("应用ID")String tenantId,
                              @RequestParam(required = true) @ApiParam("sessionKey")String sessionKey,
                              @RequestParam(required = true) @ApiParam("signature")String signature,
                              @RequestParam(required = true) @ApiParam("rawData")String rawData,
                              @RequestParam(required = true) @ApiParam("encryptedData")String encryptedData,
                              @RequestParam(required = true) @ApiParam("iv")String iv) {
        return BaseResponse.buildSuccessResponse(wechatMiniAppService.phone(tenantId, sessionKey, signature, rawData, encryptedData, iv));
    }
    /**
     * 接收微信服务器认证消息
     */
    @ApiOperation(value = "小程序接受微信服务器认证消息", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = WxMaPhoneNumberInfo.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/{tenantId}/authGet", produces = "text/plain;charset=utf-8")
    public String authGet(@PathVariable @ApiParam(name = "应用ID") String tenantId,
                          @RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {
        return wechatMiniAppService.checkSignature(tenantId, signature, timestamp, nonce, echostr);
    }
    /**
     * 接受微信请求消息
     */
    @ApiOperation(value = "接受微信请求消息", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = WxMaPhoneNumberInfo.class)})
    @RequestMapping(method = RequestMethod.POST, value = "/{tenantId}/authGet", produces = "text/plain;charset=utf-8")
    public String handleMessage(@PathVariable @ApiParam(name = "应用ID") String tenantId,
                                @RequestBody String requestBody,
                                @RequestParam(name = "msg_signature", required = false) String msgSignature,
                                @RequestParam(name = "encrypt_type", required = false) String encryptType,
                                @RequestParam(name = "signature", required = false) String signature,
                                @RequestParam("timestamp") String timestamp,
                                @RequestParam("nonce") String nonc) {
        return wechatMiniAppService.handleMessage(tenantId, requestBody, msgSignature, encryptType, signature, timestamp, nonc);
    }
    /**
     * 上传临时素材
     *
     * @return 素材的media_id列表，实际上如果有的话，只会有一个
     */
    @ApiOperation(value = "上传临时素材", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = List.class)})
    @RequestMapping(method = RequestMethod.POST, value = "/{tenantId}/upload")
    public BaseResponse uploadMedia(@PathVariable @ApiParam(name = "应用ID") String tenantId,
                                    HttpServletRequest request){

        CommonsMultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());

        if (!resolver.isMultipart(request)) {
            return BaseResponse.buildSuccessResponse(Lists.newArrayList());
        }

        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        Iterator<String> it = multiRequest.getFileNames();
        List<String> result = Lists.newArrayList();
        while (it.hasNext()) {
            try {
                MultipartFile file = multiRequest.getFile(it.next());
                File newFile = new File(Files.createTempDir(), file.getOriginalFilename());
                this.logger.info("filePath is ：" + newFile.toString());
                file.transferTo(newFile);
                WxMediaUploadResult uploadResult = wechatMiniAppService.uploadMedia(tenantId, newFile);
                this.logger.info("media_id ： " + uploadResult.getMediaId());
                result.add(uploadResult.getMediaId());
            } catch (IOException e) {
                this.logger.error(e.getMessage(), e);
                return BaseResponse.buildFailResponse(400, "IO读取异常");
            }
        }
        return BaseResponse.buildSuccessResponse(request);
    }

    /**
     * 下载临时素材
     */
    /**
     * 上传临时素材
     *
     * @return 素材的media_id列表，实际上如果有的话，只会有一个
     */
    @ApiOperation(value = "下载临时素材", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = WxMaPhoneNumberInfo.class)})
    @RequestMapping(method = RequestMethod.POST, value = "/{tenantId}/download/{mediaId}")
    public File getMedia(@PathVariable @ApiParam(name = "应用ID") String tenantId,
                         @PathVariable @ApiParam(name = "素材ID") String mediaId){
        return wechatMiniAppService.getMedia(tenantId, mediaId);
    }

}